package ias.deepsearch.com.helper.util.net;


import android.content.Context;
import android.widget.Toast;

import com.socks.library.KLog;
import com.squareup.okhttp.ResponseBody;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import cn.pedant.SweetAlert.SweetAlertDialog;

import ias.deepsearch.com.helper.ui.adapter.MyAppInfoRecyclerViewAdapter;
import ias.deepsearch.com.helper.util.normal.Constants;
import ias.deepsearch.com.helper.util.normal.FileUtil;
import ias.deepsearch.com.helper.util.normal.Utils;
import rx.Observable;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.functions.Func1;
import rx.functions.FuncN;
import rx.schedulers.Schedulers;

/**
 * Created by vector on 16/12/26.
 */

public class EngineUpdater {
    Context context;
    SweetAlertDialog updateDialog;
    MyAppInfoRecyclerViewAdapter.OnItemCheckedListener myListener;
    public EngineUpdater(Context context, MyAppInfoRecyclerViewAdapter.OnItemCheckedListener listener) {
        this.context = context;
        myListener = listener;
    }

    public void start(int type){
        updateEngine(type);
    }


    //type为1表示强制更新
    void updateEngine(final int type) {
        updateDialog = new SweetAlertDialog(context, SweetAlertDialog.PROGRESS_TYPE)
                .setTitleText("正在更新本地引擎");
        updateDialog.show();
        Observable.create(new Observable.OnSubscribe<List<String>>() {
            @Override
            public void call(Subscriber<? super List<String>> dexes){
                //TODO 现在只是看本地引擎有没有，没有就下载，应该考虑本地引擎也有更新的时候（需要增加个接口）
                List<String> localEngines = FileUtil.getLocalEngines();
                List<String> remoteEngines = FileUtil.getApkMD5List();
                List<String> targetEngines = new ArrayList<String>();
                if(type == 0 && !Utils.isEmpty(localEngines)) {
                    KLog.v(Constants.NORMAL_TAG, "==has some local engines===");
                    for (String remoteEngine : remoteEngines) {
                        if(!localEngines.contains(remoteEngine+".dex")){
                            KLog.v(Constants.NORMAL_TAG, "==lack of engine: " + remoteEngine);
                            targetEngines.add(remoteEngine);
                        }
                    }
                }else{
                    targetEngines = remoteEngines;
                }
                dexes.onNext(targetEngines);
            }
        }).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<List<String>>() {
                    @Override
                    public void call(List dexes) {
                        downloadEngine(dexes);
                    }
                });
    }


    public void updateEngine(int position, String app_name, String md5){
        updateDialog = new SweetAlertDialog(context, SweetAlertDialog.PROGRESS_TYPE)
                .setTitleText("正在更新"+ app_name + "的本地引擎");
        updateDialog.show();
        downloadEngine(position, md5);
    }

    void downloadEngine(final List<String> dexes){
        if (Utils.isEmpty(dexes)) {
            Toast.makeText(context, "本地引擎更新成功！", Toast.LENGTH_SHORT).show();
            updateDialog.cancel();
            return;
        }
        Observable[] dexObservables = new Observable[dexes.size()];
        int i = 0;
        for (String dex : dexes) {
            String target = dex + ".dex";
            dexObservables[i++] = RetrofitSingleton.getApiService(context).loadDex(target).onExceptionResumeNext(Observable.<ResponseBody>just(null));
        }

        Observable.zip(dexObservables, new FuncN<String>() {
            @Override
            public String call(Object... args) {

                File targetFolder = new File(Constants.LOCAL_ENGINE_PATH);
                if(!targetFolder.exists()){
                    targetFolder.mkdir();
                }

                for (int i = 0; i < args.length; i++) {

                    if (args[i] == null)
                        continue;
                    ResponseBody response = (ResponseBody) args[i];
                    try {
                        InputStream is = response.byteStream();
                        File file = new File(Constants.LOCAL_ENGINE_PATH, dexes.get(i) + ".dex");
                        FileOutputStream fos = new FileOutputStream(file);
                        BufferedInputStream bis = new BufferedInputStream(is);
                        byte[] buffer = new byte[1024];
                        int len;
                        while ((len = bis.read(buffer)) != -1) {
                            fos.write(buffer, 0, len);
                            fos.flush();
                        }
                        fos.close();
                        bis.close();
                        is.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                return null;
            }
        }).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        KLog.v(Constants.NORMAL_TAG, "=====download successful=====");
                        Toast.makeText(context, "更新本地引擎成功！", Toast.LENGTH_SHORT).show();
                        updateDialog.cancel();
                    }
                }, new Action1<Throwable>() {

                    @Override
                    public void call(Throwable throwable) {
                        KLog.v(Constants.NORMAL_TAG, throwable.getMessage());
                    }
                });
    }



    void downloadEngine(final int position, final String dex){
        final String target = dex + ".dex";
        Observable<ResponseBody> dexObservable = RetrofitSingleton.getApiService(context).loadDex(target);

        dexObservable.map(new Func1<ResponseBody, String>() {
            @Override
            public String call(ResponseBody response) {
                File targetFolder = new File(Constants.LOCAL_ENGINE_PATH);
                if(!targetFolder.exists()){
                    targetFolder.mkdir();
                }
                try {
                    InputStream is = response.byteStream();
                    File file = new File(Constants.LOCAL_ENGINE_PATH, target);
                    FileOutputStream fos = new FileOutputStream(file);
                    BufferedInputStream bis = new BufferedInputStream(is);
                    byte[] buffer = new byte[1024];
                    int len;
                    while ((len = bis.read(buffer)) != -1) {
                        fos.write(buffer, 0, len);
                        fos.flush();
                    }
                    fos.close();
                    bis.close();
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return null;
            }
        }).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        KLog.v(Constants.NORMAL_TAG, "=====download successful=====");
                        Toast.makeText(context, "更新本地引擎成功！", Toast.LENGTH_SHORT).show();
                        updateDialog.cancel();
                    }
                }, new Action1<Throwable>() {

                    @Override
                    public void call(Throwable throwable) {
                        Toast.makeText(context, throwable.getMessage(), Toast.LENGTH_SHORT).show();
                        KLog.v(Constants.NORMAL_TAG, throwable.getMessage());
                        updateDialog.cancel();
                        myListener.onItemChanged(position, false);
                    }
                });
    }
}